package com.qujia.station.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qujia.station.domain.FinanceStatementEnterprise;
import com.qujia.station.domain.FinanceStatementStation;
import com.qujia.station.domain.PayWay;
import com.qujia.station.domain.form.FinanceStatementQueryForm;
import com.qujia.station.domain.vo.FinanceStatement;
import com.qujia.station.mapper.FinanceStatementEnterpriseMapper;
import com.qujia.station.mapper.FinanceStatementStationMapper;
import com.qujia.station.service.IFinanceStatementEnterpriseService;
import com.qujia.station.service.IFinanceStatementService;
import com.qujia.station.service.IFinanceStatementStationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class FinanceStatementServiceImpl implements IFinanceStatementService {

    @Autowired
    private IFinanceStatementStationService financeStatementStationService;
    @Autowired
    private IFinanceStatementEnterpriseService financeStatementEnterpriseService;

    public FinanceStatement countStationStatement(Long stationId, LocalDateTime beginTime, LocalDateTime endTime){
        FinanceStatementStationMapper baseMapper = (FinanceStatementStationMapper) financeStatementStationService.getBaseMapper();
        FinanceStatement statement = new FinanceStatement();
        statement.setStationId(stationId);
        FinanceStatement oilData = baseMapper.countOilDataByDay(stationId, beginTime, endTime);
        FinanceStatement cardData = baseMapper.countCardDataByDay(stationId, beginTime, endTime);
        oilData = oilData != null ? oilData : statement;
        cardData = cardData != null ? cardData : statement;

        statement.setOilPayableAmount(oilData.getOilPayableAmount());
        statement.setOilDiscountAmount(oilData.getOilDiscountAmount());
        statement.setOilBalancePaymentAmount(oilData.getOilBalancePaymentAmount());
        statement.setOilWithdrawalAmount(oilData.getOilWithdrawalAmount());
        statement.setChargeAmount(cardData.getChargeAmount());
        statement.setChargeGiveAmount(cardData.getChargeGiveAmount());
        if(cardData.getChargeAmount() !=null){
            PayWay payWay = baseMapper.selectStationPayWay(stationId);
            if (payWay != null && "1".equals(payWay.getChannelFeePayer()) ) {
                BigDecimal k = new BigDecimal("1000");
                BigDecimal withed = cardData.getChargeAmount()
                        .multiply(k.subtract(payWay.getServiceCharge()))
                        .divide(k,BigDecimal.ROUND_HALF_EVEN);
                statement.setChargeWithdrawalAmount(withed);
            }else{
                statement.setChargeWithdrawalAmount(cardData.getChargeAmount());
            }
        }
        statement.setWithdrawalAmount(sumDecimals(oilData.getOilWithdrawalAmount(),statement.getChargeWithdrawalAmount()));
        return statement;
    }

    public FinanceStatement countEnterpriseStatement1(Long enterpriseId, LocalDateTime beginTime, LocalDateTime endTime){
        FinanceStatementEnterpriseMapper baseMapper = (FinanceStatementEnterpriseMapper) financeStatementEnterpriseService.getBaseMapper();
        FinanceStatement statement = new FinanceStatement();
        statement.setEnterpriseId(enterpriseId);
        FinanceStatement oilData = baseMapper.countOilDataByDay(enterpriseId, beginTime, endTime);
        FinanceStatement cardData = baseMapper.countCardDataByDay(enterpriseId, beginTime, endTime);
        oilData = oilData != null ? oilData : statement;
        cardData = cardData != null ? cardData : statement;

        statement.setOilPayableAmount(oilData.getOilPayableAmount());
        statement.setOilDiscountAmount(oilData.getOilDiscountAmount());
        statement.setOilBalancePaymentAmount(oilData.getOilBalancePaymentAmount());
        statement.setOilWithdrawalAmount(oilData.getOilWithdrawalAmount());
        statement.setChargeAmount(cardData.getChargeAmount());
        statement.setChargeGiveAmount(cardData.getChargeGiveAmount());
        statement.setChargeWithdrawalAmount(cardData.getChargeWithdrawalAmount());
        statement.setWithdrawalAmount(sumDecimals(oilData.getOilWithdrawalAmount(),statement.getChargeWithdrawalAmount()));
        return statement;
    }

    public FinanceStatement countEnterpriseStatement(Long enterpriseId, LocalDateTime beginTime, LocalDateTime endTime){
        FinanceStatementEnterpriseMapper baseMapper = (FinanceStatementEnterpriseMapper) financeStatementEnterpriseService.getBaseMapper();
        return baseMapper.countEnterpriseStatementByDay(enterpriseId, beginTime,endTime);
    }

    public List<FinanceStatement> queryHistoryStationStatement(FinanceStatementQueryForm query){
        FinanceStatementStation statement = new FinanceStatementStation();
        statement.setStationId(query.getStationId());
        statement.setEnterpriseId(query.getEnterpriseId());
        QueryWrapper<FinanceStatementStation> wrapper = new QueryWrapper<>(statement);
        LocalDateTime beginDate = query.getBeginDate();
        LocalDateTime endDate = query.getEndDate();
        if(beginDate != null && endDate != null && beginDate.isBefore(endDate)){
            wrapper.between("count_date",beginDate,endDate);
        }
        List<FinanceStatementStation> list = financeStatementStationService.list(wrapper);
        return list.stream().map(item -> (FinanceStatement) item).collect(Collectors.toList());
    }

    public List<FinanceStatement> queryHistoryEnterpriseStatement(FinanceStatementQueryForm query){
        FinanceStatementEnterprise statement = new FinanceStatementEnterprise();
        statement.setEnterpriseId(query.getEnterpriseId());
        QueryWrapper<FinanceStatementEnterprise> wrapper = new QueryWrapper<>(statement);
        LocalDateTime beginDate = query.getBeginDate();
        LocalDateTime endDate = query.getEndDate();
        if(beginDate != null && endDate != null && beginDate.isBefore(endDate)){
            wrapper.between("count_date",beginDate,endDate);
        }
        List<FinanceStatementEnterprise> list = financeStatementEnterpriseService.list(wrapper);
        return list.stream().map(item -> (FinanceStatement) item).collect(Collectors.toList());
    }

    public FinanceStatement countStatementByDate(FinanceStatementQueryForm form){
        if(form.getStationId() != null){
            return countStationStatement(form.getStationId(),form.getBeginDate(),form.getEndDate());
        }else if(form.getEnterpriseId() != null){
            return countEnterpriseStatement1(form.getEnterpriseId(),form.getBeginDate(),form.getEndDate());
        }
        return null;
    }

    public List<FinanceStatement> queryHistoryStatement(FinanceStatementQueryForm form){
        if (form.getBeginDate() != null) {
            form.setBeginDate(form.getBeginDate().with(LocalTime.of(0,0,0)));
        }
        if (form.getEndDate() != null) {
            form.setEndDate(form.getEndDate().with(LocalTime.of(0,0,0)));
        }
        if(form.getStationId() != null){
            return queryHistoryStationStatement(form);
        }else if(form.getEnterpriseId() != null){
            return queryHistoryEnterpriseStatement(form);
        }
        return Collections.emptyList();
    }

    private BigDecimal sumDecimals(BigDecimal... decimals){
        BigDecimal base = null;
        for (BigDecimal decimal : decimals) {
            if (decimal == null) {
                continue;
            }
            if (base == null) {
                base = decimal;
                continue;
            }
            base = base.add(decimal);
        }
        return base;
    }
}
